<template>
  <el-container class="widget-edit-container button-edit-container" @mousemove="updateMousePosition">
    <el-aside class="aside-left">
      <el-card shadow="never" body-class="aside-card-body">
        <template #header>
          <span>
            <svg-icon icon-class="el-set-up" />
            {{ i18nt('designer.componentLib') }}
          </span>
        </template>
        <el-scrollbar
          class="components-scrollbar"
          :style="{ height: scrollerHeight + 'px' }"
          always
        >
          <ul @dragover="onComponentDragOver">
            <li
              v-for="component in widgetList"
              :key="component.type"
              :class="{
                'field-widget-item': true,
                'field-widget-item-disabled': !designer || component.disabled
              }"
              :title="component.displayName"
              :draggable="designer && !component.disabled ? true : false"
              @dblclick="addFieldByDbClick(component)"
              @dragstart="onComponentDragStart(component, $event)"
            >
              <span
                ><svg-icon :icon-class="component.icon" class-name="color-svg-icon" />{{
                  i18nt(`designer.widgetLabel.${component.type}`)
                }}</span
              >
            </li>
          </ul>
        </el-scrollbar>
      </el-card>
    </el-aside>
    <el-main class="widget-edit-main">
      <el-scrollbar class="widget-designer-scroll" style="height: 488px" always>
        <div
          class="widget-designer"
          :style="{ width: canvasWidth + 60 + 'px', height: canvasHeight + 60 + 'px' }"
        >
          <div ref="horizontalRuler" class="ruler horizontal-ruler"></div>
          <div ref="verticalRuler" class="ruler vertical-ruler"></div>
          <div class="widget-canvas-cantainer">
            <div
              ref="widgetCanvasRef"
              class="widget-canvas button-edit-canvas"
              :style="canvasStyle"
              @click="canvasClickHandler"
              @dragover="onDragOver"
              @drop="onDrop"
              @contextmenu.stop="onContextMenu"
            >
              <!-- 组件渲染部分 -->
              <component
                :is="getWidgetName(cWidget)"
                v-for="(cWidget, index) in widgetChildren"
                :key="cWidget.id"
                :ref="cWidget.id"
                :field="cWidget"
                :designer="designer"
                :settings="settings"
                :parent-list="widgetChildren"
                :index-of-parent-list="index"
                :parent-widget="widget"
                :design-state="true"
                :widget-edit="true"
                :style="{
                  left: cWidget.options.x + 'px',
                  top: cWidget.options.y + 'px'
                }"
              ></component>
            </div>
          </div>
        </div>
      </el-scrollbar>
    </el-main>
    <el-aside class="aside-right">
      <el-tabs type="card" :style="{ height: settingsPanelHeight + 'px' }">
        <el-tab-pane :label="i18nt('designer.hint.widgetSetting')">
          <el-scrollbar
            class="property-setting-scrollbar"
            :style="{ height: scrollerHeight + 'px' }"
            always
          >
            <template v-if="selectedWidget">
              <el-form
                :model="optionModel"
                size="small"
                label-position="right"
                label-width="90px"
                class="setting-form"
                :disabled="widgetSettingDisabled"
                @submit.prevent
              >
                <el-collapse v-model="collapseNames" class="setting-collapse">
                  <el-collapse-item v-if="appearancePropList.length > 0" name="1" title="外观">
                    <template v-for="editorName in appearancePropList" :key="editorName">
                      <component
                        :is="editorName"
                        :designer="designer"
                        :selected-widget="selectedWidget"
                        :option-model="optionModel"
                      ></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="positionSizePropList.length > 0" name="2" title="位置尺寸">
                    <template v-for="editorName in positionSizePropList" :key="editorName">
                      <component
                        :is="editorName"
                        :designer="designer"
                        :selected-widget="selectedWidget"
                        :option-model="optionModel"
                        :parent-widget="widget"
                      ></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="miscPropList.length > 0" name="3" title="杂项">
                    <template v-for="editorName in miscPropList" :key="editorName">
                      <component
                        :is="editorName"
                        :designer="designer"
                        :selected-widget="selectedWidget"
                        :option-model="optionModel"
                      ></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="fontPropList.length > 0" name="4" title="字体">
                    <template v-for="editorName in fontPropList" :key="editorName">
                      <component
                        :is="editorName"
                        :designer="designer"
                        :selected-widget="selectedWidget"
                        :option-model="optionModel"
                      ></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="dataPropList.length > 0" name="3" title="数据">
                    <template v-for="editorName in dataPropList" :key="editorName">
                      <component
                        :is="editorName"
                        :designer="designer"
                        :selected-widget="selectedWidget"
                        :option-model="optionModel"
                      ></component>
                    </template>
                  </el-collapse-item>

                  <el-collapse-item v-if="eventPropList.length > 0" name="6" title="事件">
                    <template v-for="editorName in eventPropList" :key="editorName">
                      <component
                        :is="editorName"
                        :designer="designer"
                        :selected-widget="selectedWidget"
                        :option-model="optionModel"
                      ></component>
                    </template>
                  </el-collapse-item>
                </el-collapse>
              </el-form>
            </template>
          </el-scrollbar>
        </el-tab-pane>

        <el-tab-pane label='内部组件' style="padding: 10px 0;overflow-y: auto;" :style="{ height: scrollerHeight + 'px' }">
          <template v-for="(widget2, ind2) in pageWidgetList" :key="widget2.id">
            <div @click="selectNode(ind2)"
              class="baseNodeCls"
              :class="{selectNodeCls : ind2 ==seleNodeInd }" >
              {{widget2.name}}
            </div>
          </template>
        </el-tab-pane>
      </el-tabs>
    </el-aside>

    <el-dialog
      v-model="showWidgetEventDialogFlag"
      :title="`${i18nt(`designer.widgetLabel.${selectedWidget && selectedWidget.type}`)}组件${curEventName}编辑`"
      :show-close="true"
      class="code-editor-dialog small-padding-dialog"
      append-to-body
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :destroy-on-close="true"
      draggable
    >
    <div class="variable-info" v-if="selectedWidget">
    <p>控件ID : {{selectedWidget.options.name}}</p>
    <p >当前函数的通用变量(以下变量只在当前控件的范围有效)</p>
<p>objId : 指的是当前控件的ID（{{ selectedWidget.options.name }}），可以通过函数get_obj_width、get_obj_height、set_obj_width、set_obj_attr_ext1等函数获取和设置控件信息</p>
      <p>value : 当前控件的值</p>
  </div>
      <code-editor
        ref="ecEditor"
        v-model="eventHandlerCode"
        :mode="'lua'"
        :readonly="false"
      ></code-editor>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showWidgetEventDialogFlag = false">
            {{ i18nt('designer.hint.cancel') }}</el-button
          >
          <el-button type="success" @click="handleWidgetPreview">
        {{ i18nt('designer.hint.simulate') }}</el-button>
          <el-button type="primary" @click="saveEventHandler">
            {{ i18nt('designer.hint.confirm') }}</el-button
          >
        </div>
      </template>
    </el-dialog>
  </el-container>
</template>

<script>
import * as ELECTRON from '@/electron'
import Ruler from '@scena/ruler'
import { widgetList as BFS, buttonWidgetList } from '@/designer/widget-panel/widgetsConfig'
import {
  APPEARANCE_PROPERTIES,
  POSITION_SIZE_PROPERTIES,
  FONT_PROPERTIES,
  DATA_PROPERTIES,
  MISC_PROPERTIES,
  EVENT_PROPERTIES
} from '@/designer/setting-panel/propertyRegister'
import * as CONST from '@/designer/const'
import { useMouseInElement } from '@vueuse/core'
import { ref } from 'vue'
import { GET_IMAGE_RESOURCE, GET_IMAGE_RESOURCE_RESULT } from '@/designer/event'
import emitter from '@/mixins/emitter'
import { deepClone, generateId } from '@/utils/util'

//就是右下角的框框
export default {
  name: 'ButtonEdit',
  componentName: 'ButtonEdit',
  mixins: [emitter],
  provide() {
    return {
      refList: this.widgetRefList,
      getOptionData: () => this.optionData,
      globalModel: {
        formModel: this.formModel
      }
    }
  },
  props: {
    designer: Object,
    settings: Object,
    widget: Object
  },
  setup() {
    const widgetCanvasRef = ref(null)
    const { elementX, elementY, elementWidth, elementHeight } = useMouseInElement(widgetCanvasRef)
    return {
      widgetCanvasRef,
      elementX,
      elementY,
      elementWidth,
      elementHeight
    }
  },
  data() {
    return {
      // 允许作为子组件的组件列表
      widgetList: [],

      // 滚动条高度
      scrollerHeight: 400,

      backgroundImage: '',

      collapseNames: ['1', '2', '3', '4', '5', '6'],
      formModel: {},
      widgetRefList: {},
      vRuler: null,
      hRuler: null,

      seleNodeInd: -1,

      showWidgetEventDialogFlag: false,
      eventHandlerCode: '',
      curEventName: '',
      clipboard: null,
    lastPasteTime: 0,
    originalCopyMethod: null,
    originalPasteMethod: null,
    }
  },
  computed: {
    pageWidgetList() {
      let li = []
      let widgetL = this.widgetChildren
      Object.keys(widgetL).forEach(function(key) {
        li.push({name: widgetL[key].options.name, checked: false})
      })
      return li
    },
    optionModel() {
      return this.selectedWidget && this.selectedWidget.options
    },
    widgetChildren() {
      return this.widget.widgetList || []
    },
    selectedWidget() {
      return this.designer ? this.designer.selectedWidget : null
    },
    widgetSettingDisabled() {
      if (this.selectedWidget && this.selectedWidget.id === this.widget.id) {
        return true
      }

      return false
    },
    backgroundPositionX() {
      const align = this.widget.options.pngAlign
      if (
        align === CONST.ALIGN_TYPE.LV_ALIGN_TOP_LEFT ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_LEFT_MID ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_BOTTOM_LEFT
      ) {
        return 'left'
      } else if (
        align === CONST.ALIGN_TYPE.LV_ALIGN_TOP_RIGHT ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_RIGHT_MID ||
        align === CONST.ALIGN_TYPE.LV_ALIGN_BOTTOM_RIGHT
      ) {
        return 'right'
      } else {
        return 'center'
      }
    },
    appearancePropList() {
      if (!this.optionModel) {
        return []
      }
      // console.log('=====> ')
      // console.log(APPEARANCE_PROPERTIES)
      return Object.keys(APPEARANCE_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return APPEARANCE_PROPERTIES[prop]
        })
    },
    positionSizePropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(POSITION_SIZE_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return POSITION_SIZE_PROPERTIES[prop]
        })
    },
    fontPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(FONT_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return FONT_PROPERTIES[prop]
        })
    },
    dataPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(DATA_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return DATA_PROPERTIES[prop]
        })
    },
    miscPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(MISC_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return MISC_PROPERTIES[prop]
        })
    },
    eventPropList() {
      if (!this.optionModel) {
        return []
      }
      return Object.keys(EVENT_PROPERTIES)
        .filter((prop) => {
          return Object.hasOwn(this.optionModel, prop)
        })
        .map((prop) => {
          return EVENT_PROPERTIES[prop]
        })
    },
    canvasWidth() {
      return this.widget.options.width
    },
    canvasHeight() {
      return this.widget.options.height
    },
    bgType() {
      return this.widget.options.bgType
    },
    pngId() {
      return this.widget.options.pngId
    },
    bgColor() {
      return this.widget.options.bgColor
    },
    canvasStyle() {
      const baseStyle = {
        width: this.canvasWidth + 'px',
        height: this.canvasHeight + 'px',
        backgroundPositionX: this.backgroundPositionX,
        backgroundPositionY: 'center',
        backgroundRepeat: 'no-repeat',
        opacity: 1
      }
      if (this.bgType === CONST.PAGE_BG_TYPE.IMG) {
        baseStyle.backgroundImage = this.backgroundImage
      } else {
        baseStyle.backgroundColor = this.bgColor
      }
      return baseStyle
    }
  },
  watch: {
    // 监听背景类型变化
  bgType(newVal, oldVal) {
    if (newVal !== oldVal) {
      if (newVal === CONST.PAGE_BG_TYPE.COLOR) {
        // 当切换到纯色背景时，清除背景图片
        this.backgroundImage = '';
      } else if (newVal === CONST.PAGE_BG_TYPE.IMG && this.pngId) {
        // 当切换到图片背景且有图片ID时，加载图片
        this.$nextTick(() => {
          this.$emitter.emit(GET_IMAGE_RESOURCE, this.pngId);
        });
      }
    }
  },
    // 监听clipboard变化，同步到全局
  clipboard: {
    handler(newVal) {
      if (newVal && newVal.widget) {
        const parentInstance = this.getParentDesignerInstance();
        if (parentInstance && parentInstance.globalClipboard) {
          parentInstance.globalClipboard = deepClone(newVal);
        }
      }
    },
    deep: true
  },
    selectedWidget(newVal) {
      if(newVal == null) {
        return
      }
      let widgetL = this.widgetChildren
      // console.log(newVal)
      for (let ind in widgetL) {
        if (widgetL[ind].options.name == newVal.options.name) {
          this.seleNodeInd = ind
        }
      }
    },
    canvasHeight(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$nextTick(() => {
          this.reRenderVerticalRuler(newVal)
        })
      }
    },
    canvasWidth(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$nextTick(() => {
          this.reRenderHorizontalRuler(newVal)
        })
      }
    },
    bgType(newVal, oldVal) {
      if (newVal !== oldVal) {
        if (newVal === CONST.PAGE_BG_TYPE.IMG) {
          if (this.pngId) {
            this.$nextTick(() => {
              this.$emitter.emit(GET_IMAGE_RESOURCE, this.pngId)
            })
          }
        }
      }
    },
    pngId(newVal, oldVal) {
      if (newVal !== oldVal && newVal) {
        this.$nextTick(() => {
          this.$emitter.emit(GET_IMAGE_RESOURCE, this.newVal)
        })
      }
    }
  },
  mounted() {
    this.originalCopyMethod = this.designer?.copySelectedWidget;
  this.originalPasteMethod = this.designer?.pasteWidget;
  
  // 覆盖designer方法
  if (this.designer) {
    this.designer.copySelectedWidget = (widget) => {
      this.copyWidget(widget);
    };
    this.designer.pasteWidget = (position) => {
      this.pasteWidget(position);
    };
  }
    this.on$('editEventHandler', (eventParams) => {
      this.editEventHandler(eventParams[0], eventParams[1])
    })

    // 加载组件
    this.loadWidgets()

    this.$emitter.on(GET_IMAGE_RESOURCE_RESULT, (data) => {
      if (data && data.name === this.widget.options.pngId) {
        if (data.result) {
          this.backgroundImage = `url(${data.result.url})`
        } else {
          this.backgroundImage = ''
        }
      }
    })

    this.$emitter.on('widget-drag-end', this.handleDragEnd)

    this.$emitter.on('pasteWidget', this.pasteWidget)

    this.widgetCanvasRef = this.$refs.widgetCanvasRef

    this.reRenderHorizontalRuler(this.canvasWidth)
    this.reRenderVerticalRuler(this.canvasHeight)
  },
  unmounted() {
    this.$emitter.off('widget-drag-end', this.handleDragEnd)
    // 恢复原始方法
  if (this.designer) {
    this.designer.copySelectedWidget = this.originalCopyMethod;
    this.designer.pasteWidget = this.originalPasteMethod;
  }
  },
  // 在activated和deactivated生命周期中添加
activated() {
  // Button组件激活时，从全局剪贴板同步
  this.syncClipboardFromGlobal();
  console.log('Button激活，剪贴板已同步');
},

deactivated() {
  // Button组件失活时，确保全局剪贴板有最新数据
  if (this.clipboard && this.clipboard.widget) {
    const parentInstance = this.getParentDesignerInstance();
    if (parentInstance && parentInstance.globalClipboard) {
      parentInstance.globalClipboard = deepClone(this.clipboard);
      console.log('Button失活，剪贴板已同步到全局');
    }
  }
},
  methods: {
    syncClipboardFromGlobal() {
    // 获取父组件的全局剪贴板
    const parentInstance = this.getParentDesignerInstance();
    if (parentInstance && parentInstance.globalClipboard) {
      this.clipboard = deepClone(parentInstance.globalClipboard);
      console.log('从全局剪贴板同步成功:', this.clipboard);
    }
  },
    updateMousePosition(event) {
    this.lastMousePosition = {
      x: event.clientX,
      y: event.clientY
    };
  },
    // 修改copyWidget方法
copyWidget(widget = null) {
  const widgetToCopy = widget || this.selectedWidget;
  if (!widgetToCopy) {
    this.$message.error('请先选择组件');
    return;
  }
  
  // 深拷贝组件
  const widgetCopy = deepClone(widgetToCopy);
  
  // 同时设置到designer和本地clipboard
  if (this.originalCopyMethod) {
    this.originalCopyMethod.call(this.designer, widgetCopy);
  }
  
  this.clipboard = {
    widget: widgetCopy,
    timestamp: Date.now(),
    source: 'button'
  };
  
  // 同步到全局剪贴板
  const parentInstance = this.getParentDesignerInstance();
  if (parentInstance && parentInstance.globalClipboard) {
    parentInstance.globalClipboard = deepClone(this.clipboard);
  }
  
  console.log('按钮内复制成功并同步到全局:', this.clipboard);
  //this.$message.success('复制成功');
},

// 添加获取父设计器实例的方法
getParentDesignerInstance() {
  // 向上查找父组件实例
  let parent = this.$parent;
  while (parent) {
    if (parent.$options.name === 'VFormDesigner') {
      return parent;
    }
    parent = parent.$parent;
  }
  return null;
},
    selectNode(index) {
      // console.log(index)
      // console.log(this.designer)
      console.log(this.widgetChildren[index])

      this.designer.selectedWidget = this.widgetChildren[index]
    },
    // 修改pasteWidget方法
// 确保pasteWidget方法可以被外部调用
pasteWidget(position = null) {
  try {
    // 防止快速重复粘贴
    const now = Date.now();
    if (now - this.lastPasteTime < 500) return;
    this.lastPasteTime = now;
    
    // 优先使用全局剪贴板
    const parentInstance = this.getParentDesignerInstance();
    const useGlobalClipboard = parentInstance && parentInstance.globalClipboard && 
                              parentInstance.globalClipboard.widget;
    
    const clipboardSource = useGlobalClipboard ? parentInstance.globalClipboard : this.clipboard;
    
    if (!clipboardSource || !clipboardSource.widget) {
      this.$message.error('请先复制组件');
      return;
    }

    const newWidget = deepClone(clipboardSource.widget);
    const newId = generateId();
    newWidget.id = `${newWidget.type}${newId}`;
    newWidget.options.id = this.designer.getLastId();
    newWidget.options.name = `${newWidget.type}${newWidget.options.id}`;
    
    if (newWidget.options.userId) {
      newWidget.options.userId = this.designer.getLastUserId();
    }
    
    // 处理子组件
    if (newWidget.widgetList) {
      this.copyWidgetListForButton(newWidget.widgetList, newWidget);
    }
    
    // 获取容器(按钮)尺寸
    const containerWidth = this.canvasWidth;
    const containerHeight = this.canvasHeight;
    
    // 获取组件尺寸(带默认值)
    const widgetWidth = newWidget.options.width || 100;
    const widgetHeight = newWidget.options.height || 100;
    
    // 检查并调整组件尺寸
    if (widgetWidth > containerWidth || widgetHeight > containerHeight) {
      this.$message.warning('组件尺寸超过按钮容器，已自动调整');
      newWidget.options.width = Math.min(widgetWidth, containerWidth);
      newWidget.options.height = Math.min(widgetHeight, containerHeight);
    }

    // 计算粘贴位置
    const canvasRect = this.$refs.widgetCanvasRef.getBoundingClientRect();
    let pasteX, pasteY;
    
    if (position && canvasRect) {
      // 计算相对于按钮画布的位置
      pasteX = position.x - canvasRect.left;
      pasteY = position.y - canvasRect.top;
      
      // 转换为设计器坐标
      const scale = 1;
      pasteX = Math.round(pasteX / scale);
      pasteY = Math.round(pasteY / scale);
    } else {
      // 默认偏移
      pasteX = (clipboardSource.widget.options.x || 0) + 20;
      pasteY = (clipboardSource.widget.options.y || 0) + 20;
    }

    // 边界检查
    pasteX = Math.max(0, Math.min(pasteX, containerWidth - newWidget.options.width));
    pasteY = Math.max(0, Math.min(pasteY, containerHeight - newWidget.options.height));

    newWidget.options.x = pasteX;
    newWidget.options.y = pasteY;

    // 设置父按钮信息
    newWidget.options.parentId = this.widget.id;
    newWidget.options.baseId = this.widget.options.id;

    // 添加到按钮内部
    this.widget.widgetList.push(newWidget);
    this.designer.setSelected(newWidget);
    this.designer.emitHistoryChange();
    
    // 更新剪贴板为当前粘贴的组件（便于连续粘贴）
    this.copyWidget(newWidget);
    
    this.$message.success('粘贴成功');
    console.log("在button组件内粘贴");
  } catch (error) {
    console.error('粘贴失败:', error);
    this.$message.error(`粘贴失败: ${error.message}`);
  }
},

// 添加处理子组件的方法
copyWidgetListForButton(widgetList, parentWidget) {
  widgetList.forEach((widget) => {
    const tempId = generateId();
    widget.id = widget.type.replace(/-/g, '') + tempId;
    
    const lastId = this.designer.getLastId();
    widget.options.id = lastId;
    widget.options.name = `${widget.type}${lastId}`;
    
    if (widget.options.userId) {
      widget.options.userId = this.designer.getLastUserId();
    }
    
    // 设置父组件信息
    widget.options.parentId = parentWidget.id;
    widget.options.baseId = parentWidget.options.id;
    
    // 递归处理子组件
    if (widget.widgetList) {
      this.copyWidgetListForButton(widget.widgetList, widget);
    }
  });
},
    canvasClickHandler() {
      this.designer.setSelected(this.widget)
    },
    onContextMenu(event) {
      event.preventDefault()
      this.designer.setSelected(null)

      this.$emitter.emit('showContextMenu', {
        clientX: event.clientX,
        clientY: event.clientY,
        designerId: this.designer.id
      })
    },
    onDragOver(evt) {
      evt.preventDefault()

      const widget = this.designer.dragWidget
      if (this.$refs[widget.id] && this.$refs[widget.id].length > 0) {
        const translateX = this.elementX - widget.options.x - widget.offset.x
        const translateY = this.elementY - widget.options.y - widget.offset.y

        const widgetInstance = this.$refs[widget.id][0]
        widgetInstance.$el.style.transform = `translate(${translateX}px, ${translateY}px)`
      }
    },

    onDrop(evt) {
  evt.preventDefault();
  
  if (evt.dataTransfer.effectAllowed === 'copy') {
    const widget = this.designer.dragWidget;
    
    // 检查组件是否适合容器
    const containerWidth = this.canvasWidth;
    const containerHeight = this.canvasHeight;
    const widgetWidth = widget.options.width || 100;
    const widgetHeight = widget.options.height || 100;
    
    if (widgetWidth > containerWidth || widgetHeight > containerHeight) {
      this.$message.warning('组件尺寸大于容器，将自动调整大小');
      widget.options.width = Math.min(widgetWidth, containerWidth);
      widget.options.height = Math.min(widgetHeight, containerHeight);
    }
    
    this.designer.addDragWidget(widget, this.widget);
    this.updateWidgetPosition(widget);
    this.designer.drag(null);
    this.designer.emitHistoryChange();
  }
},

    handleDragEnd(widget) {
      if (this.designer.hasWidget(widget, this.widget.widgetList)) {
        this.updateWidgetPosition(widget)

        if (this.$refs[widget.id] && this.$refs[widget.id].length > 0) {
          const widgetInstance = this.$refs[widget.id][0]
          widgetInstance.$el.style.transform = `translate(0, 0)`
        }

        // 清除拖拽元素
        this.designer.drag(null)
        // 保存操作历史
        this.designer.emitHistoryChange()
      }
    },

    loadWidgets() {
      this.widgetList = BFS.filter((widget) => buttonWidgetList.includes(widget.type)).map(
        (config) => {
          return {
            ...config,
            displayName: this.i18nt(`designer.widgetLabel.${config.type}`)
          }
        }
      )
    },
    handleFieldWidgetClone(origin) {
      return this.designer.copyNewFieldWidget(origin, this.widget)
    },
    onComponentDragStart(widget, evt) {
      const widgetCopy = this.designer.copyNewFieldWidget(widget)
      widgetCopy.offset = {
        x: evt.offsetX,
        y: evt.offsetY
      }
      this.designer.drag(widgetCopy)
      evt.dataTransfer.effectAllowed = 'copy'
    },
    onComponentDragOver(evt) {
      evt.preventDefault()
    },
    addFieldByDbClick(widget) {
      this.designer.addFieldByDbClick(widget, this.widget)
    },
    reRenderHorizontalRuler(width) {
      if (this.hRuler) {
        this.$refs.horizontalRuler.removeChild(this.$refs.horizontalRuler.querySelector('canvas'))
        this.hRuler = null
      }

      this.hRuler = new Ruler(this.$refs.horizontalRuler, {
        type: 'horizontal',
        width: width + 30,
        height: 30,
        backgroundColor: '#daeaff',
        lineColor: '#000000',
        textColor: '#154a93',
        textAlign: 'right'
      })
    },
    reRenderVerticalRuler(height) {
      if (this.vRuler) {
        this.$refs.verticalRuler.removeChild(this.$refs.verticalRuler.querySelector('canvas'))
        this.vRuler = null
      }
      this.vRuler = new Ruler(this.$refs.verticalRuler, {
        type: 'vertical',
        width: 30,
        height: height + 30,
        backgroundColor: '#daeaff',
        lineColor: '#000000',
        textColor: '#154a93'
      })
    },
    getWidgetName(widget) {
      return widget.type + '-widget'
    },

    updateWidgetPosition(widget) {
  if (!widget) return;

  this.$nextTick(() => {
    if (widget.offset) {
      // 获取容器尺寸
      const containerWidth = this.canvasWidth;
      const containerHeight = this.canvasHeight;
      
      // 获取组件尺寸（带默认值）
      const widgetWidth = widget.options.width || 100;
      const widgetHeight = widget.options.height || 100;

      // 计算边界安全的位置
      let newX = this.elementX - widget.offset.x;
      let newY = this.elementY - widget.offset.y;

      // 确保组件不超出容器边界
      newX = Math.max(0, Math.min(newX, containerWidth - widgetWidth));
      newY = Math.max(0, Math.min(newY, containerHeight - widgetHeight));

      // 应用四舍五入后的位置
      widget.options.x = Math.round(newX);
      widget.options.y = Math.round(newY);
      
      // 如果组件过大则自动调整
      if (widgetWidth > containerWidth) {
        widget.options.width = containerWidth;
        this.$message.warning('组件宽度已调整以适应容器');
      }
      if (widgetHeight > containerHeight) {
        widget.options.height = containerHeight;
        this.$message.warning('组件高度已调整以适应容器');
      }

      delete widget.offset;
    }
  });
},

    getWidgetRef(widgetName, showError = false) {
      let foundRef = this.widgetRefList[widgetName]
      if (!foundRef && !!showError) {
        this.$message.error(this.i18nt('designer.hint.refNotFound') + widgetName)
      }
      return foundRef
    },

    clearWidgetRefList() {
      Object.keys(this.widgetRefList).forEach((widgetRef) => {
        delete this.widgetRefList[widgetRef]
      })
    },

    deleteWidgetRef(widgetRefName) {
      delete this.widgetRefList[widgetRefName]
    },
    editEventHandler(eventName) {
      this.curEventName = eventName
      this.eventHandlerCode = this.selectedWidget.options[eventName] || ''

      this.showWidgetEventDialogFlag = true
    },
    handleWidgetPreview() {
  // 先保存代码但不关闭对话框
  this.saveEventHandler(false).then((success) => {
    if (success) {
      // 触发页面仿真
      this.$emitter.emit('CLEAR_DEBUG_LOG')
      this.$emitter.emit(
        'START_PAGE_DEBUG',
        (this.designer && this.designer.options.name) || ''
      )
    }
  })
},

saveEventHandler(closeDialog = true) {
  return new Promise((resolve) => {
    const codeHints = this.$refs.ecEditor.getEditorAnnotations()
    let syntaxErrorFlag = false
    if (!!codeHints && codeHints.length > 0) {
      codeHints.forEach((chItem) => {
        if (chItem.type === 'error') {
          syntaxErrorFlag = true
        }
      })

      if (syntaxErrorFlag) {
        this.$message.error(this.i18nt('designer.setting.syntaxCheckWarning'))
        resolve(false)
        return
      }
    }

    this.selectedWidget.options[this.curEventName] = this.eventHandlerCode
    if (closeDialog) {
      this.showWidgetEventDialogFlag = false
    }
    resolve(true)
  })
},
    // saveEventHandler() {
    //   const codeHints = this.$refs.ecEditor.getEditorAnnotations()
    //   let syntaxErrorFlag = false
    //   if (!!codeHints && codeHints.length > 0) {
    //     codeHints.forEach((chItem) => {
    //       if (chItem.type === 'error') {
    //         syntaxErrorFlag = true
    //       }
    //     })

    //     if (syntaxErrorFlag) {
    //       this.$message.error(this.i18nt('designer.setting.syntaxCheckWarning'))
    //       return
    //     }
    //   }

    //   this.selectedWidget.options[this.curEventName] = this.eventHandlerCode
    //   this.showWidgetEventDialogFlag = false
    // }
  }
}
</script>

<style lang="scss" scoped>
.variable-info {
  padding: 5px 12px;
  margin-bottom: 5px;
  background-color: #f5f7fa;
  border-radius: 8px;
  border-left: 4px solid #409eff;
  font-size: 12px;
  color: #606266;
}
.selectNodeCls {
  background: #f0d292;
}
.baseNodeCls {
  padding: 6px 15px;
  box-sizing: border-box;
  font-size: 12px;
  &:hover {
    cursor: pointer;
  }
}
.widget-edit-container {
  position: relative;

  :deep(.el-card) {
    margin-top: 0;

    .el-card__header {
      background-color: #daeaff;
      color: #083772;
      font-size: 12px;
      padding: 10px 15px;
    }

    .el-card__body {
      padding: 4px;
      border: #6593cf solid 1px;
    }
  }

  .aside-left {
    width: 180px;

    ul {
      padding-left: 10px; /* 重置IE11默认样式 */
      margin: 0; /* 重置IE11默认样式 */
      margin-block-start: 0;
      margin-block-end: 0.25em;
      padding-inline-start: 10px;

      &:after {
        content: '';
        display: block;
        clear: both;
      }

      .field-widget-item {
        display: inline-block;
        height: 24px;
        line-height: 24px;
        font-size: 11px;
        width: 98px;
        margin: 2px 6px 6px 0;
        cursor: move;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        background: #fff;
        border: 1px solid #e8e9eb;
        border-radius: 4px;
        padding: 0 8px;

        &:hover {
          background: #ffeaa6;
          border-color: #e49c05;
          color: $--color-primary;

          .color-svg-icon {
            color: $--color-primary;
          }
        }
      }

      .field-widget-item.field-widget-item-disabled {
        color: #808080;
        cursor: not-allowed;

        &:hover {
          background: #e8e9eb;
          border-color: #e8e9eb;

          .color-svg-icon {
            color: #808080;
            fill: #808080;
          }
        }
      }
    }
  }

  .widget-edit-main {
    padding-top: 0;
    padding-bottom: 0;

    .widget-designer-scroll {
      .widget-designer {
        position: relative;
        background: #daeaff;
        overflow: hidden;

        .ruler {
          position: absolute;
          top: 0;
          left: 0;
        }

        .ruler.horizontal-ruler {
          left: 30px;
          right: 0;
        }

        .ruler.vertical-ruler {
          top: 30px;
          bottom: 0;
        }

        .widget-canvas-cantainer {
          position: absolute;
          left: 30px;
          right: 30px;
          top: 30px;
          bottom: 30px;
          //background: #ffffff;
          

          :deep(.el-row) {
            padding: 2px;
            border: 1px dashed rgba(170, 170, 170, 0.75);
          }

          .widget-canvas {
            position: absolute;
            overflow: hidden;
          }
        }
      }
    }
  }

  .aside-right {
    width: 300px;

    .setting-form {
      padding: 0 6px;

      :deep(.el-form-item__label) {
        font-size: 11px;
        overflow: hidden;
        white-space: nowrap;
      }

      :deep(.el-form-item--small.el-form-item) {
        margin-bottom: 10px;
      }

      :deep(.el-slider) {
        .el-slider__runway {
          margin-right: 16px;
        }

        .el-slider__input {
          width: 85px !important;
        }
      }

      :deep(.el-select) {
        width: 178px !important;
      }
    }
  }
}
</style>
